package com.yami.trading.huobi.hobi.internal;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.yami.trading.bean.cms.Infomation;
import com.yami.trading.bean.data.domain.*;
import com.yami.trading.common.util.RedisUtil;
import com.yami.trading.huobi.data.DataCache;
import com.yami.trading.huobi.data.internal.DepthTimeObject;
import com.yami.trading.huobi.data.internal.KlineService;
import com.yami.trading.huobi.data.internal.TradeTimeObject;
import com.yami.trading.huobi.hobi.http.HttpHelper;
import com.yami.trading.huobi.hobi.http.HttpMethodType;
import com.yami.trading.service.cms.InfomationService;
import com.yami.trading.service.item.ItemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 新浪k线图采集
 */
@Component
public class XinLangDataServiceImpl {

    // https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_seurusd_1_1688818651726=/NewForexService.getMinKline?symbol=fx_seurusd&scale=1&datalen=2000
    public final static String klineUrl = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_s{1}_1_{3}=/NewForexService.getMinKline?symbol=fx_s{1}&scale={2}&datalen=2000";

    public final static String klineDay = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_s{1}{2}=/NewForexService.getDayKLine?symbol=fx_s{1}&_={2}";

    /**
     * live
     */
    //public final static String live = "https://rjkjd.com/stock/api/live/getLiveRates";
    public final static String live = "https://hq.sinajs.cn/rn=hwat&list=";


    private static Logger logger = LoggerFactory.getLogger(XinLangDataServiceImpl.class);

    @Autowired
    private KlineService klineService;
    @Autowired
    private ItemService itemService;


    public static void main(String[] args) {
        XinLangDataServiceImpl service = new XinLangDataServiceImpl();
//        List<Kline> sz300750 = service.buildOneYearPeriod("AAPL");
//        System.out.println(sz300750.size());
        List<Kline> eurusd = service.getTimeseriesByPeriodOneDay("EURUSD");
        System.out.println(JSONObject.toJSONString(eurusd));
    }


    /**
     * 获取原始的K线图数据
     *
     * @param symbol
     * @param cookie
     * @return
     */
    public String getRawTimeseriesByMinute(String symbol, String cookie) {
        long nowTs = System.currentTimeMillis();
        long begin = nowTs;
        String url = StrUtil.format(klineUrl, symbol, begin, "1m");
        return HttpHelper.sendGetHttp(url, null, cookie);
    }

    public List<Realtime> realtimeSingle(String symbol) {
        List<Realtime> list = new ArrayList<Realtime>();
        try {
            Map<String, String> param = new HashMap<>();
            param.put("currency", symbol);
            String url = live + symbol;
            String body = HttpUtil.createGet(url).header("Referer", "https://finance.sina.com.cn")
                    .execute().body();
           // String code = resultJson.getString("code");
           // JSONObject resultJson = new JSONObject();
            if (body.contains(",")) {
                String[] split = body.split(";");
                for (String s : split){
                    if (StrUtil.isBlank(s)){
                        continue;
                    }
                    String currency = s.substring(s.indexOf("=")-6,s.indexOf("="));
                    String substring = s.substring(s.indexOf("\"") + 1, s.lastIndexOf("\""));
                    if (StrUtil.isBlank(substring)){
                        String url1 ="https://hq.sinajs.cn/etag.php?_=1694574232151&list=fx_s" + currency.toLowerCase();
                        String body1 = HttpUtil.createGet(url1).header("Referer", "https://finance.sina.com.cn")
                                .execute().body();
                         substring = body1.substring(body1.indexOf("\"") + 1, body1.lastIndexOf("\""));
                    }
                    JSONObject jsonObject = new JSONObject();
                    Realtime realtime = new Realtime();
                    int decimal = itemService.getDecimal(symbol);
                    realtime.setSymbol(currency);
                    realtime.setName(currency);
                    Long timestamp = new Date().getTime();
                    if (timestamp.toString().length() > 13) {
                        timestamp = timestamp / 1000;
                    }
                    realtime.setTs(timestamp);
                    String[] data = substring.split(",");
                    realtime.setOpen(new BigDecimal(data[5]));
                    realtime.setClose(new BigDecimal(data[1]));
                    realtime.setHigh(new BigDecimal(data[6]));
                    realtime.setLow(new BigDecimal(data[7]));
                    // realtime.setMarketCapital(new BigDecimal(data[1]));
                    // realtime.setFloatMarketCapital(realtimeJson.getLong("floatMarketCapital"));
                    // realtime.setPeForecast(realtimeJson.getBigDecimal("peForecast"));
                    // realtime.setVolumeRatio(realtimeJson.getBigDecimal("volumeRatio"));
                    //realtime.setTurnoverRate(realtimeJson.getBigDecimal("turnoverRate"));
//                    BigDecimal amount = realtimeJson.getBigDecimal("amount");
//                    if (amount == null) {
//                        amount = BigDecimal.ZERO;
//                    }
                    realtime.setAmount(new BigDecimal("0"));
//                    BigDecimal volume = realtimeJson.getBigDecimal("volume");
//                    if (volume == null) {
//                        volume = BigDecimal.ZERO;
//                    }
                    realtime.setVolume(new BigDecimal("0"));
//                    realtime.setAsk(realtimeJson.getBigDecimal("ask").setScale(decimal, RoundingMode.HALF_UP));
//                    realtime.setBid(realtimeJson.getBigDecimal("bid").setScale(decimal, RoundingMode.HALF_UP));
                    list.add(realtime);
                }

            } else {
               // logger.error(" realtime()error, resultJson [ " + resultJson.toJSONString() + " ]");
            }
//            if ("ok".equals("code")) {
//                JSONArray dataArray = resultJson.getJSONArray("data");
//                for (int i = 0; i < dataArray.size(); i++) {
//                    JSONObject realtimeJson = dataArray.getJSONObject(i);
//                    Realtime realtime = new Realtime();
//                    String currency;
//                    currency = realtimeJson.getString("currency");
//                    int decimal = itemService.getDecimal(currency);
//                    realtime.setSymbol(currency);
//                    realtime.setName(currency);
//                    Long timestamp = realtimeJson.getLong("timestamp");
//                    if (timestamp.toString().length() > 13) {
//                        timestamp = timestamp / 1000;
//                    }
//                    realtime.setTs(timestamp);
//                    realtime.setOpen(realtimeJson.getBigDecimal("open").setScale(decimal, RoundingMode.HALF_UP));
//                    realtime.setClose(realtimeJson.getBigDecimal("mid").setScale(decimal, RoundingMode.HALF_UP));
//                    realtime.setHigh(realtimeJson.getBigDecimal("high").setScale(decimal, RoundingMode.HALF_UP));
//                    realtime.setLow(realtimeJson.getBigDecimal("low").setScale(decimal, RoundingMode.HALF_UP));
//                    realtime.setMarketCapital(realtimeJson.getLong("marketCapital"));
//                    realtime.setFloatMarketCapital(realtimeJson.getLong("floatMarketCapital"));
//                    realtime.setPeForecast(realtimeJson.getBigDecimal("peForecast"));
//                    realtime.setVolumeRatio(realtimeJson.getBigDecimal("volumeRatio"));
//                    realtime.setTurnoverRate(realtimeJson.getBigDecimal("turnoverRate"));
//                    BigDecimal amount = realtimeJson.getBigDecimal("amount");
//                    if (amount == null) {
//                        amount = BigDecimal.ZERO;
//                    }
//                    realtime.setAmount(amount.setScale(decimal, RoundingMode.HALF_UP));
//                    BigDecimal volume = realtimeJson.getBigDecimal("volume");
//                    if (volume == null) {
//                        volume = BigDecimal.ZERO;
//                    }
//                    realtime.setVolume(volume.setScale(decimal, RoundingMode.HALF_UP));
////                    realtime.setAsk(realtimeJson.getBigDecimal("ask").setScale(decimal, RoundingMode.HALF_UP));
////                    realtime.setBid(realtimeJson.getBigDecimal("bid").setScale(decimal, RoundingMode.HALF_UP));
//                    list.add(realtime);
//                }
//            } else {
//                logger.error(" realtime()error, resultJson [ " + resultJson.toJSONString() + " ]");
//            }
        } catch (Exception e) {
            logger.error("error", e);
        }
        return list;
    }

    public List<Realtime> realtime(String symbols) {
        List<Realtime> realtimeList = realtimeSingle(symbols);
        return realtimeList;
    }

    /**
     * 1day       历史数据  ： 周期 1年
     * 1week,1mon 历史数据  ： 周期 5年
     * 请求 350次
     */
    public Map<String, List<Kline>> getDailyWeekMonthHistory(String symbol) {
        Map<String, List<Kline>> map = new HashMap<>();
        List<Kline> oneDayPeriod = buildOneDayPeriod(symbol);

//  	public List<Kline> calculateKline(String symbol, int seq, String period, List<Kline> klineList) ;
        map.put(Kline.PERIOD_1WEEK, klineService.calculateKline(symbol, 7, Kline.PERIOD_1WEEK, oneDayPeriod));
        map.put(Kline.PERIOD_1MON, klineService.calculateKline(symbol, 30, Kline.PERIOD_1MON, oneDayPeriod));
        map.put(Kline.PERIOD_1DAY, oneDayPeriod);
        map.put(Kline.PERIOD_5DAY, klineService.calculateKline(symbol, 5, Kline.PERIOD_5DAY, oneDayPeriod));
        map.put(Kline.PERIOD_QUARTER,  klineService.calculateKline(symbol, 90, Kline.PERIOD_QUARTER, oneDayPeriod));
        map.put(Kline.PERIOD_YEAR, klineService.calculateKline(symbol, 365, Kline.PERIOD_YEAR, oneDayPeriod));

        return map;
    }

    public List<Kline> buildOneDayPeriod(String currency) {
        return getTimeseriesByPeriodOneDay(currency);

    }





    /**
     * 雪球支持120分钟的，讲120分钟的，
     * Hourly
     * 4hourly 3月
     */
    public List<Kline> getTimeseriesForFourHourly(String currency) {
        return getTimeseriesByPeriodMinute(currency, 240, Kline.PERIOD_4HOUR);
    }

    /**
     * Hourly
     * 1hourly 2个小时
     */
    public List<Kline> getTimeseriesForTwoHourly(String currency) {
        return getTimeseriesByPeriodMinute(currency, 120, Kline.PERIOD_2HOUR);
    }

    /**
     * Hourly
     * 1hourly 1月
     */
    public List<Kline> getTimeseriesForOneHourly(String currency) {
        return getTimeseriesByPeriodMinute(currency, 60, Kline.PERIOD_60MIN);
    }

    /**
     * Minute
     * 30minute 10天
     * 15minute 5天
     * 5minute  2天
     * 1minute  1天
     */
    public List<Kline> getTimeseriesOneMinute(String currency) {
        return getTimeseriesByPeriodMinute(currency, 1, Kline.PERIOD_1MIN);

    }

    /**
     * Minute
     * 30minute 10天
     * 15minute 5天
     * 5minute  2天
     * 1minute  1天
     */
    public List<Kline> getTimeseriesFiveMinute(String currency) {
        return getTimeseriesByPeriodMinute(currency, 5, Kline.PERIOD_5MIN);

    }

    /**
     * Minute
     * 30minute 10天
     * 15minute 5天
     * 5minute  2天
     * 1minute  1天
     */
    public List<Kline> getTimeseriesFifteenMinute(String currency) {
        return getTimeseriesByPeriodMinute(currency, 15, Kline.PERIOD_15MIN);

    }

    /**
     * Minute
     * 30minute 15
     * 15minute 15
     * 5minute  15
     * 1minute  15
     */
    public List<Kline> getTimeseriesThirtyMinute(String currency) {
        return getTimeseriesByPeriodMinute(currency, 30, Kline.PERIOD_30MIN);
    }

    public List<Kline> getTimeseriesByPeriodMinute(String currency, int scale, String period) {

        // https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_seurusd_1_1688818651726=/NewForexService.getMinKline?symbol=fx_seurusd&scale=1&datalen=2000
        long nowTs = System.currentTimeMillis();
        String url = klineUrl.replace("{1}", currency.toLowerCase()).replace("{3}", nowTs + "").replace("{2}", scale + "");
        List<Kline> resList = new ArrayList<>();
        String json = HttpHelper.sendGetHttp(url, "");
        if (!json.contains("(")) {
            throw new IllegalArgumentException("新浪外汇k线图采集错误");
        }
        json = json.split("\\(")[1].replace(");", "");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        JSONArray dataArray = JSONObject.parseArray(json);
        for (Object result : dataArray) {
            JSONObject data = (JSONObject) result;
            Kline kline = new Kline();
            kline.setSymbol(currency);
            kline.setPeriod(period);

            String dateTimeStr = data.getString("d");

            // 解析字符串，指定时区为上海
            ZonedDateTime dateTime = ZonedDateTime.parse(dateTimeStr, formatter.withZone(ZoneId.of("Asia/Shanghai")));

            // 转换成时间戳（毫秒）
            long ts = dateTime.toInstant().toEpochMilli();
            kline.setTs(ts);
            kline.setOpen(new BigDecimal(data.getString("o")));
            kline.setClose(new BigDecimal(data.getString("c")));
            kline.setHigh(new BigDecimal(data.getString("h")));
            kline.setLow(new BigDecimal(data.getString("l")));
            kline.setVolume(BigDecimal.ZERO);
            kline.setAmount(BigDecimal.ZERO);
            resList.add(kline);
        }

        return resList;

    }


    public List<Kline> getTimeseriesByPeriodOneDay(String currency) {

        //  public final static String klineDay = "https://vip.stock.finance.sina.com.cn/forex/api/jsonp.php/var%20_fx_s{1}{2}=/NewForexService.getDayKLine?symbol=fx_s{1}&_={2}";
        LocalDate today = LocalDate.now();


        int year = today.getYear();
        int month = today.getMonthValue();
        int day = today.getDayOfMonth();
        String dateStr = year + "_" + month + "_" + day;
        String url = klineDay.replace("{1}", currency.toLowerCase()).replace("{2}", dateStr);
        List<Kline> resList = new ArrayList<>();
        String json = HttpHelper.sendGetHttp(url, "");
        if (!json.contains("(")) {
            throw new IllegalArgumentException("新浪外汇k线图采集错误");
        }
        json = json.split("\\(")[1].replace(");", "").replace("\"", "");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String[] datas = json.split("\\|");
        for (String result : datas) {
            List<String> ds = Splitter.on(",").omitEmptyStrings().splitToList(result);
            // 解析字符串，指定时区为上海
            Kline kline = new Kline();
            kline.setSymbol(currency);

            kline.setPeriod(Kline.PERIOD_1DAY);
            LocalDate date = LocalDate.parse(ds.get(0), dateFormatter);
           //  date  = 0 , 1是开盘，2是最低。3是最高，4是收盘
            // 转换成时间戳（毫秒）
            long ts =  date.atStartOfDay(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli();
            kline.setTs(ts);
            kline.setOpen(new BigDecimal(ds.get(1)));
            kline.setClose(new BigDecimal(ds.get(4)));
            kline.setHigh(new BigDecimal(ds.get(3)));
            kline.setLow(new BigDecimal(ds.get(2)));
            kline.setVolume(BigDecimal.ZERO);
            kline.setAmount(BigDecimal.ZERO);
            resList.add(kline);
        }

        return resList;

    }



}
